package br.ufrgs.ga.operators;

import java.security.InvalidParameterException;

/**
 * Implements the genetic crossover operation.
 * @author mineiro
 *
 */
public class CrossoverOperator implements ICrossover<String> {

	public static final int DEFAULT_POINTCUT = 3;

	/**
	 * Type of crossover.
	 * @author mineiro
	 *
	 */
	public enum CrossoverType {
		Head,
		Tail
	};
	
	/**
	 * String pointcut where the crossover will occur.
	 */
	public final int pointcut;
	
	/**
	 * Crossover type, the chromosomes can exchange slices of DNA strand and combine parts to create a new strand.
	 * This field will tell how the crossover will occur, by combining the head of DNA strand of one chromosome with
	 * the tail of the other chromosome DNA strand.
	 */
	public final CrossoverType type;
	
	public CrossoverOperator() {
		this.type = CrossoverType.Head;
		this.pointcut = DEFAULT_POINTCUT;
	}
	
	public CrossoverOperator(CrossoverType type) {
		this.type = type;
		this.pointcut = DEFAULT_POINTCUT;
	}
	
	public CrossoverOperator(CrossoverType type, int pointcut) {
		this.type = type;
		this.pointcut = pointcut;
	}

	@Override
	public String execute(String dnaStrand1, String dnaStrand2) {
		if (dnaStrand1 == null || dnaStrand2 == null || dnaStrand1.isEmpty() || dnaStrand2.isEmpty()) {
			throw new InvalidParameterException("The DNA strands cannot be null or empty strings.");
		}
		
		String dnaStrandHead1 = dnaStrand1.substring(0, pointcut);
		String dnaStrandTail1 = dnaStrand1.substring(pointcut);
		String dnaStrandHead2 = dnaStrand2.substring(0, pointcut);
		String dnaStrandTail2 = dnaStrand2.substring(pointcut);
		String newDnaStrandHead = dnaStrandHead1 + dnaStrandTail2;
		String newDnaStrandTail = dnaStrandHead2 + dnaStrandTail1;
		if (type.equals(CrossoverType.Tail))
			return newDnaStrandTail;
		
		return newDnaStrandHead;
	}

	/**
	 * Pointcut where the crossover will occur.
	 * @return
	 */
	public int getPointcut() {
		return pointcut;
	}
}
